package com.zjinyin.forum.controller;

import com.sun.istack.internal.NotNull;
import com.zjinyin.forum.common.AppResult;
import com.zjinyin.forum.common.ResultCode;
import com.zjinyin.forum.config.AppConfig;
import com.zjinyin.forum.exception.ApplicationException;
import com.zjinyin.forum.model.Message;
import com.zjinyin.forum.model.User;
import com.zjinyin.forum.service.IMessageService;
import com.zjinyin.forum.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: DELL
 * Date: 2023-08-13
 * Time: 17:36
 */

@Api(tags = "站内信接口")
@Slf4j
@RestController
@RequestMapping("/message")
public class MessageController {


    @Resource
    private IMessageService messageService;

    @Resource
    private IUserService userService;


    /**
     * 发送站内信
     *
     * @param request       获取用户 Id
     * @param receiveUserId 接收者 Id
     * @param content       发送内容
     */
    @ApiOperation("发送站内信")
    @PostMapping("/sendMessage")
    public AppResult sendMessage(HttpServletRequest request,
                                 @ApiParam("接收者 id") @RequestParam("receiveUserId") @NotNull Long receiveUserId,
                                 @ApiParam("信内容") @RequestParam("content") @NotNull String content) {
        // 1. 获取当前登录用户状态
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);

        // 用户禁言状态
        if (user.getState() == 1) {
            log.warn("UserId : " + user.getId() + " " + ResultCode.FAILED_USER_BANNED);
            return AppResult.failed(ResultCode.FAILED_USER_BANNED);
        }

        // 2. 不能给自己发站内信
        if (receiveUserId.equals(user.getId())) {
            log.warn("receiveUserId : " + receiveUserId + " " + ResultCode.FAILED + " 无法给自己发送站内信");
            return AppResult.failed(ResultCode.FAILED + " 无法给自己发送站内信");
        }

        // 3. 检验接受者是否存在
        User existsUser = userService.selectByPrimaryKey(receiveUserId);
        if (existsUser == null || existsUser.getDeleteState() == 1) {
            log.warn("receiveUserId : " + receiveUserId + " " + ResultCode.FAILED_USER_NOT_EXISTS);
            return AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE + " 接收者状态异常");
        }

        // 4. 封装消息对象
        Message updateMessage = new Message();
        // 设置发送者 -- 自己发送
        updateMessage.setPostUserId(user.getId());
        // 设置接收者
        updateMessage.setReceiveUserId(receiveUserId);
        // 设置发送内容
        updateMessage.setContent(content);

        // 5. 写入数据库
        messageService.create(updateMessage);

        return AppResult.success();
    }


    /**
     * 获取当前登录用户的未读站内信数量
     *
     * @param request 请求头获取当前接收者为当前用户
     */
    @ApiOperation("获取当前登录用户的未读站内信数量")
    @GetMapping("/getUnReadMessage")
    public AppResult<Integer> selectUnReadMessage(HttpServletRequest request) {
        // 1. 获取当前用户信息
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);

        // 2. 接收者即为当前用户
        if (user.getDeleteState() == 1) {
            log.warn("receiveUserId" + user.getId() + " " + ResultCode.FAILED_FORBIDDEN);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_FORBIDDEN));
        }

        // 3. 获取数目
        Integer count = messageService.selectUnReadMessage(user.getId());

        return AppResult.success(count);
    }


    /**
     * 获取当前登录用户站内信的所有内容
     *
     * @return
     */
    @ApiOperation("获取当前用户的站内信")
    @GetMapping("/getAllMessage")
    public AppResult<List<Message>> getAllMessage(HttpServletRequest request) {

        // 1. 获取当前登陆用户
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);

        if (user.getDeleteState() == 1) {
            log.warn("userId : " + user.getId() + " " + ResultCode.FAILED_USER_NOT_EXISTS);
            return AppResult.failed(ResultCode.ERROR_SERVICES);
        }

        // 2. 查询站内信
        List<Message> list = messageService.selectByReceiveUserId(user.getId());

        return AppResult.success(list);

    }


    /**
     * 更新站内信状态
     *
     * @param id 站内信 id
     */
    @ApiOperation("更新站内信状态")
    @PostMapping("/updateStateById")
    public AppResult updateStateById(@ApiParam("站内信 id") @RequestParam("id") @NotNull Long id, HttpServletRequest request) {
        // 1. 根据 id 查询站内信是否存在
        Message message = messageService.selectById(id);

        if (message == null || message.getDeleteState() == 1) {
            return AppResult.failed(ResultCode.Message_NOT_EXISTS);
        }

        // 2. 检验是否为当前用户的站内信
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);
        // 不是自己的站内信无法访问
        if (!user.getId().equals(message.getReceiveUserId())) {
            log.warn("站内信 id : " + user.getId() + " " + ResultCode.FAILED_UNAUTHORIZED);
            return AppResult.failed(ResultCode.FAILED_UNAUTHORIZED);
        }

        // 3. 更新指定站内信状态 -- 从未读变成已读
        messageService.updateStateById(id, (byte) 1);

        return AppResult.success();
    }


    /**
     * 根据站内信 id 回复指定站内信, 并将该站内信状态更新为已回复
     *
     * @param repliedId 站内信 id
     * @param content   回复指定站内信的内容
     */
    @ApiOperation("回复指定站内信, 并将状态更新为已回复")
    @PostMapping("/repliedIdMessage")
    public AppResult repliedMessage(@ApiParam("站内信 id") @RequestParam("repliedId") @NotNull Long repliedId,
                                    @ApiParam("回复指定站内信的内容") @RequestParam("content") @NotNull String content,
                                    HttpServletRequest request) {

        // 1. 获取当前登录用户状态
        HttpSession session = request.getSession(false);

        User user = (User) session.getAttribute(AppConfig.USER_SESSION);
        if (user.getState() == 1) {
            return AppResult.failed(ResultCode.FAILED_USER_BANNED);
        }

        // 2. 根据 repliedId 查询指定站内信
        Message existsMessage = messageService.selectById(repliedId);

        if (existsMessage == null || existsMessage.getDeleteState() == 1) {
            throw new ApplicationException(AppResult.failed(ResultCode.Message_NOT_EXISTS));
        }

        // 检验站内信是否是自己发的
        if (user.getId().equals(existsMessage.getPostUserId())) {
            return AppResult.failed("暂不支持回复自己 ");
        }

        if (!user.getId().equals(existsMessage.getReceiveUserId())) {
            return AppResult.failed(ResultCode.FAILED_UNAUTHORIZED + ", 此消息不是你的, 无法回复 ");
        }

        // 不支持重复回复功能需要设置
//        if(existsMessage.getState() == 2) {
//            return AppResult.failed("此消息消息已回复");
//        }

        // 3. 创建回复信息对象
        Message message = new Message();
        message.setPostUserId(user.getId());
        message.setReceiveUserId(existsMessage.getPostUserId());
        message.setContent(content);

        // 4. 写入数据库
        messageService.replyMessage(repliedId, message);

        return AppResult.success();
    }
}
